package com.rede.didiok.admin.service.impl;

import java.util.*;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rede.didiok.admin.dao.LinkDao;
import com.rede.didiok.admin.entity.LinkEntity;
import com.rede.didiok.admin.service.LinkService;
import com.rede.didiok.common.constant.conf.MessageConf;
import com.rede.didiok.common.constant.conf.RedisConf;
import com.rede.didiok.common.constant.conf.SQLConf;
import com.rede.didiok.common.constant.conf.SysConf;
import com.rede.didiok.common.constant.conf.base.BaseSQLConf;
import com.rede.didiok.common.constant.global.Constants;
import com.rede.didiok.common.dto.admin.LinkDto;
import com.rede.didiok.common.enums.LinkStatusEnum;
import com.rede.didiok.common.enums.StatusEnum;
import com.rede.didiok.common.feign.FileFeignClient;
import com.rede.didiok.common.utils.CheckUtils;
import com.rede.didiok.common.utils.RedisUtil;
import com.rede.didiok.common.utils.ResultUtil;
import com.rede.didiok.common.utils.StringUtils;
import com.rede.didiok.common.utils.business.RabbitMqUtil;
import com.rede.didiok.common.utils.business.WebUtil;

@Slf4j
@Service("linkService")
public class LinkServiceImpl extends ServiceImpl<LinkDao, LinkEntity> implements LinkService {

    @Resource
    private LinkDao linkDao;
    @Resource
    private FileFeignClient fileFeignClient;
    @Autowired
    private WebUtil webUtil;
    @Autowired
    private RabbitMqUtil rabbitMqUtil;
    @Autowired
    private RedisUtil redisUtil;


    /***************************** admin:start **************************/
    // region  didiok-admin

    @Override
    public IPage<LinkEntity> getPageList(LinkDto linkDto) {
        QueryWrapper<LinkEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(linkDto.getKeyword()) && !StringUtils.isEmpty(linkDto.getKeyword().trim())) {
            queryWrapper.like(SQLConf.TITLE, linkDto.getKeyword().trim());
        }
        if (linkDto.getLinkStatus() != null) {
            queryWrapper.eq(SQLConf.LINK_STATUS, linkDto.getLinkStatus());
        }
        if (StringUtils.isNotEmpty(linkDto.getOrderByAscColumn())) {
            String column = StringUtils.underLine(new StringBuffer(linkDto.getOrderByAscColumn())).toString();
            queryWrapper.orderByAsc(column);
        } else if (StringUtils.isNotEmpty(linkDto.getOrderByDescColumn())) {
            String column = StringUtils.underLine(new StringBuffer(linkDto.getOrderByDescColumn())).toString();
            queryWrapper.orderByDesc(column);
        } else {
            queryWrapper.orderByDesc(SQLConf.SORT);
        }
        Page<LinkEntity> page = new Page<>();
        page.setCurrent(linkDto.getCurrentPage());
        page.setSize(linkDto.getPageSize());
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        IPage<LinkEntity> pageList = this.page(page, queryWrapper);
        List<LinkEntity> linkList = pageList.getRecords();
        final StringBuffer fileUids = new StringBuffer();
        // 给友情链接添加图片
        linkList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                fileUids.append(item.getFileUid() + SysConf.FILE_SEGMENTATION);
            }
        });
        String pictureList = null;
        Map<String, String> pictureMap = new HashMap<>();
        if (fileUids != null) {
            pictureList = fileFeignClient.getPicture(fileUids.toString(), SysConf.FILE_SEGMENTATION);
        }
        List<Map<String, Object>> picList = webUtil.getPictureMap(pictureList);
        picList.forEach(item -> {
            pictureMap.put(item.get(SysConf.UID).toString(), item.get(SysConf.URL).toString());
        });
        for (LinkEntity item : linkList) {
            //获取图片
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                List<String> pictureUidsTemp = StringUtils.changeStringToString(item.getFileUid(), Constants.SYMBOL_COMMA);
                List<String> pictureListTemp = new ArrayList<>();

                pictureUidsTemp.forEach(picture -> {
                    pictureListTemp.add(pictureMap.get(picture));
                });
                item.setPhotoList(pictureListTemp);
            }
        }
        pageList.setRecords(linkList);
        return pageList;
    }

    @Override
    public String addLink(LinkDto linkDto) {
        LinkEntity link = new LinkEntity();
        link.setTitle(linkDto.getTitle());
        link.setSummary(linkDto.getSummary());
        link.setUrl(linkDto.getUrl());
        link.setClickCount(0);
        link.setLinkStatus(linkDto.getLinkStatus());
        link.setSort(linkDto.getSort());
        link.setEmail(linkDto.getEmail());
        link.setFileUid(linkDto.getFileUid());
        link.setStatus(StatusEnum.ENABLE);
        link.setUpdateTime(new Date());
        link.insert();

        // 友链从申请状态到发布状态，需要发送邮件到站长邮箱
        if (StringUtils.isNotEmpty(link.getEmail()) && CheckUtils.checkEmail(link.getEmail())) {
            log.info("发送友链申请通过的邮件通知");
            String linkApplyText = "<a href=\" " + link.getUrl() + "\">" + link.getTitle() + "</a> 站长，您申请的友链已经成功上架~";
            rabbitMqUtil.sendSimpleEmail(link.getEmail(), linkApplyText);
        }

        // 删除Redis中的BLOG_LINK
        deleteRedisRankMemberLinkList();

        return ResultUtil.successWithMessage(MessageConf.INSERT_SUCCESS);
    }

    @Override
    public String editLink(LinkDto linkDto) {
        LinkEntity link = this.getById(linkDto.getUid());
        Integer linkStatus = link.getLinkStatus();
        link.setTitle(linkDto.getTitle());
        link.setSummary(linkDto.getSummary());
        link.setLinkStatus(linkDto.getLinkStatus());
        link.setUrl(linkDto.getUrl());
        link.setSort(linkDto.getSort());
        link.setEmail(linkDto.getEmail());
        link.setFileUid(linkDto.getFileUid());
        link.setUpdateTime(new Date());
        link.updateById();

        // 友链从申请状态到发布状态，需要发送邮件到站长邮箱
        if (StringUtils.isNotEmpty(link.getEmail()) && CheckUtils.checkEmail(link.getEmail())) {
            if (LinkStatusEnum.APPLY.equals(linkStatus) && LinkStatusEnum.PUBLISH.equals(linkDto.getLinkStatus())) {
                log.info("发送友链申请通过的邮件通知");
                String linkApplyText = "<a href=\" " + link.getUrl() + "\">" + link.getTitle() + "</a> 站长，您申请的友链已经成功上架~";
                rabbitMqUtil.sendSimpleEmail(link.getEmail(), linkApplyText);
            }
        }

        // 删除Redis中的BLOG_LINK
        deleteRedisRankMemberLinkList();

        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    @Override
    public String deleteLink(LinkDto linkDto) {
        LinkEntity link = this.getById(linkDto.getUid());
        link.setStatus(StatusEnum.DISABLED);
        link.setUpdateTime(new Date());
        link.updateById();

        // 删除Redis中的BLOG_LINK
        deleteRedisRankMemberLinkList();

        return ResultUtil.successWithMessage(MessageConf.DELETE_SUCCESS);
    }

    @Override
    public String stickLink(LinkDto linkDto) {
        LinkEntity link = this.getById(linkDto.getUid());
        //查找出最大的那一个
        QueryWrapper<LinkEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc(SQLConf.SORT);
        Page<LinkEntity> page = new Page<>();
        page.setCurrent(0);
        page.setSize(1);
        IPage<LinkEntity> pageList = this.page(page, queryWrapper);
        List<LinkEntity> list = pageList.getRecords();
        LinkEntity maxSort = list.get(0);
        if (StringUtils.isEmpty(maxSort.getUid())) {
            return ResultUtil.errorWithMessage(MessageConf.PARAM_INCORRECT);
        }
        if (maxSort.getUid().equals(link.getUid())) {
            return ResultUtil.errorWithMessage(MessageConf.OPERATION_FAIL);
        }
        Integer sortCount = maxSort.getSort() + 1;
        link.setSort(sortCount);
        link.setUpdateTime(new Date());
        link.updateById();
        // 删除Redis中的BLOG_LINK
        deleteRedisRankMemberLinkList();
        return ResultUtil.successWithMessage(MessageConf.OPERATION_SUCCESS);
    }

    // endregion
    /***************************** admin:end **************************/



    /***************************** web:start **************************/
    // region didiok-web

    @Override
    public List<LinkEntity> getListByPageSize(Integer pageSize) {
        QueryWrapper<LinkEntity> queryWrapper = new QueryWrapper<>();
        Page<LinkEntity> page = new Page<>();
        page.setCurrent(1);
        page.setSize(pageSize);
        queryWrapper.eq(BaseSQLConf.LINK_STATUS, LinkStatusEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.orderByDesc(BaseSQLConf.SORT);
        IPage<LinkEntity> pageList = linkDao.selectPage(page, queryWrapper);
        return pageList.getRecords();
    }

    /**
     * 根据用户uid和友链名获取一条连接
     *
     * @param userUid
     * @param title
     * @return
     */
    @Override
    public LinkEntity getLinkByUserUidAndTitle(String userUid, String title) {
        QueryWrapper<LinkEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.USER_UID, userUid);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(SQLConf.TITLE, title);
        queryWrapper.last(SysConf.LIMIT_ONE);
        return this.getOne(queryWrapper);
    }

    /**
     * 保存一条友链
     *
     * @param linkDto
     * @return
     */
    @Override
    public String addOneLink(LinkDto linkDto) {
        LinkEntity link = new LinkEntity();
        link.setTitle(linkDto.getTitle());
        link.setSummary(linkDto.getSummary());
        link.setUrl(linkDto.getUrl());
        link.setClickCount(0);
        link.setLinkStatus(linkDto.getLinkStatus());
        link.setSort(linkDto.getSort());
        link.setEmail(linkDto.getEmail());
        link.setFileUid(linkDto.getFileUid());
        link.setStatus(StatusEnum.ENABLE);
        link.setUpdateTime(new Date());
        link.insert();

        return link.getUid();
    }
    // endregion
    /***************************** web:end **************************/

    @Override
    public String addLinkCount(String uid) {
        if (StringUtils.isEmpty(uid)) {
            return ResultUtil.errorWithMessage(MessageConf.PARAM_INCORRECT);
        }
        LinkEntity link = this.getById(uid);
        if (link != null) {
            int count = link.getClickCount() + 1;
            link.setClickCount(count);
            link.updateById();
        } else {
            return ResultUtil.errorWithMessage(MessageConf.PARAM_INCORRECT);
        }
        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    /**
     * 删除Redis中的友链列表
     */
    private void deleteRedisRankMemberLinkList() {
        // 删除Redis中的BLOG_LINK
        Set<String> keys = redisUtil.keys(RedisConf.RANK_MEMBER_LINK + Constants.SYMBOL_COLON + "*");
        redisUtil.delete(keys);
    }

}